package com.mikufufu.blog.utils;

import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;

/**
 * 加密工具类
 * 
 */
@Slf4j
public class EncryptionUtils {

    /**
     * MD5加密
     * @param source 需要加密的字符串
     * @return 结果 String 加密后的字符串
     */
    public static String md5(String source){
        try {
            // 获取 MD5 算法实例对象
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] md5 = messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));
            // 将处理后的字节转成 16 进制，得到最终 32 个字符
            StringBuilder stringBuilder = new StringBuilder();
            for (byte b : md5) {
                stringBuilder.append(String.format("%02x", b));
            }
            return stringBuilder.toString();

        } catch (NoSuchAlgorithmException e) {
            log.error("MD5 加密失败", e);
        }
        return null;
    }

    /**
     * MD5加密
     * @param source 需要加密的字符串
     * @param salt 盐
     * @return 结果 String 加密后的字符串
     */
    public static String md5(String source, String salt) {
        return md5(source + salt);
    }


    /**
     * 检查给定的源字符串和盐值经过MD5加密后是否与给定的编码字符串匹配。
     *
     * @param sourceStr 源字符串，即将被加密的字符串。
     * @param salt 盐值，用于加强加密的字符串。
     * @param encodedStr 加密字符串，用于比对的已编码字符串。
     * @return boolean 如果给定的源字符串和盐值加密后与编码字符串匹配，则返回true；否则返回false。
     */
    public static boolean md5Matches(String sourceStr, String salt, String encodedStr) {
        // 根据源字符串和盐值计算MD5值，并与给定的编码字符串进行比较
        return encodedStr.equals(md5(sourceStr, salt));
    }

    /**
     * SHA-256加密
     * @param source 需要加密的字符串
     * @return 结果 String 加密后的字符串
     */
    public static String sha256(String source){
        try {
            // 获取 SHA-256 算法实例对象
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            byte[] sha256 = messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));
            // 将处理后的字节转成 16 进制，得到最终 32 个字符
            StringBuilder stringBuilder = new StringBuilder();
            for (byte b : sha256) {
                stringBuilder.append(String.format("%02x", b));
            }
            return stringBuilder.toString();

        } catch (NoSuchAlgorithmException e) {
            log.error("SHA-256 加密失败", e);
        }
        return null;
    }

    /**
     * 判断是否与加密值相同 SHA-256
     * @param sourceStr 源字符串
     * @param encodedStr 加密后字符
     * @return 结果
     */
    public static boolean sha256Matches(String sourceStr, String encodedStr) {
        return encodedStr.equals(sha256(sourceStr));
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要加密的字符串：");
        String source = sc.next();
        String encodedStr = sha256(source);
        System.out.println(encodedStr);
    }
}
